#include "myGame.h"

int idx_current_anim = 0;
const int PLAYER_ANIM_NUM = 6;
const int PLAYER_SPEED = 2;

const int PLAYER_WIDTH = 80;//玩家宽度
const int PLAYER_HEIGHT = 80;//玩家高度
const int SHADOW_WIDTH = 32;

IMAGE imgplayer_left[PLAYER_ANIM_NUM];
IMAGE imgplayer_right[PLAYER_ANIM_NUM];

IMAGE img_shadow;

Animation anim_left_player(_T("img/player_left_%d.png"), 6, 45);
Animation anim_right_player(_T("img/player_right_%d.png"), 6, 45);

POINT player_pos = { 500,500 };


inline void putimage_alpha(int x, int y, IMAGE* img) {
    // 获取图像的宽度
    int w = img->getwidth();
    // 获取图像的高度
    int h = img->getheight();
    // 使用AlphaBlend函数进行图像混合绘制
    AlphaBlend(GetImageHDC(NULL), x, y, w, h,
        GetImageHDC(img), 0, 0, w, h, { AC_SRC_OVER,0,255,AC_SRC_ALPHA });
}

void DrawPlayer(int delta, int dir_x) {
    // 计算影子在x轴上的位置
    int pos_shadow_x = player_pos.x + (PLAYER_WIDTH / 2 - SHADOW_WIDTH / 2);
    int pos_shadow_y = player_pos.y + PLAYER_HEIGHT - 8;
    putimage_alpha(pos_shadow_x, pos_shadow_y, &img_shadow);

    // 静态变量，表示玩家是否面向左方
    static bool facing_left = false;
    if (dir_x < 0)
        // 如果玩家向左移动，则设置facing_left为true
        facing_left = true;
    else if (dir_x > 0)
        // 如果玩家向右移动，则设置facing_left为false
        facing_left = false;

    // 根据facing_left的值判断播放哪个动画
    if (facing_left)
        // 如果面向左方，则播放左侧的玩家动画
        anim_left_player.Play(player_pos.x, player_pos.y, delta);
    else
        // 如果面向右方，则播放右侧的玩家动画
        anim_right_player.Play(player_pos.x, player_pos.y, delta);
}


//生成新敌人
void TryGenerateEnemy(vector<Enemy*>& enemy_list) {
    const int INTERVAL = 100;
    static int counter = 0;
    if ((++counter) % INTERVAL == 0) {
        enemy_list.push_back(new Enemy());
    }
}

//更新子弹位置
void UpdateBullets(vector<Bullet>& bullet_list, const Player& player) {
    const double RADIAL_SPEED = 0.0045;//径向波动速度
    const double TANGENT_SPEED = 0.0055;//切向波动速度
    double radian_interval = 2 * 3.14159 / bullet_list.size();//子弹之间的弧度间隔
    POINT player_position = player.GetPosition();
    double radius = 100 + 25 * sin(GetTickCount() * RADIAL_SPEED);
    for (size_t i = 0; i < bullet_list.size(); i++) {
        double radian = GetTickCount() * TANGENT_SPEED + radian_interval * i;
        bullet_list[i].position.x = player_position.x + player.FRAME_WIDTH / 2 + (int)(radius * sin(radian));
        bullet_list[i].position.y = player_position.y + player.FRAME_HEIGHT / 2 + (int)(radius * cos(radian));
    }
}

//绘制玩家得分
void DrawPlayerScore(int score) {
    static TCHAR text[64];
    _stprintf_s(text, _T("your score: %d"), score);

    setbkmode(TRANSPARENT);
    settextcolor(RGB(255, 85, 185));
    outtextxy(10, 10, text);
}

void gamestart() {
     
        bool running = true;
        // 消息结构体
        ExMessage msg;
        // 图片结构体
        IMAGE img_backgroud;
        //玩家得分
        int score = 0;
        //实例化玩家
        Player player;
        vector<Enemy*> enemy_list;
        vector<Bullet> bullet_list(3);//修改括号内的数值可以改变子弹数量

        //加载音乐
        mciSendString(_T("open mus/bgm.mp3 alias bgm"), NULL, 0, NULL);
        mciSendString(_T("open mus/hit.wav alias hit"), NULL, 0, NULL);
        mciSendString(_T("play bgm repeat from 0"), NULL, 0, NULL);

        // 加载背景图片
        loadimage(&img_backgroud, _T("./img/background.png"));
        putimage(0, 0, &img_backgroud);
        // 开始批量绘制
        BeginBatchDraw();

        while (running)
        {
            // 获取当前时间戳
            DWORD start_time = GetTickCount();

            // 检查消息队列中是否有消息
            while (peekmessage(&msg))
            {
                player.ProgressEvent(msg);
            }
            player.Move();
            TryGenerateEnemy(enemy_list);

            for (Enemy* enemy : enemy_list) {
                enemy->Move(player);
            }
            //检测敌人与玩家的碰撞
            for (Enemy* enemy : enemy_list) {
                if (enemy->CheckPlayerCollision(player)) {
                    MessageBox(GetHWnd(), _T("DEAD"), _T("please try again."), MB_OK);
                    running = false;
                    break;
                }
            }
            //检测子弹和敌人的碰撞
            for (Enemy* enemy : enemy_list) {
                for (const Bullet& bullet : bullet_list) {
                    if (enemy->CheckBulletCollision(bullet)) {
                        mciSendString(_T("play hit from 0"), NULL, 0, NULL);
                        enemy->Hurt();
                        score++;
                    }
                }
            }
            //移除生命值归零的敌人
            for (size_t i = 0; i < enemy_list.size(); i++) {
                Enemy* enemy = enemy_list[i];
                if (!enemy->CheckAlive()) {
                    swap(enemy_list[i], enemy_list.back());
                    enemy_list.pop_back();
                    delete enemy;
                }
            }
            // 清除设备上的内容
            cleardevice();

            // 在设备上绘制背景图片
            putimage(0, 0, &img_backgroud);
            player.Draw(1000 / 144);

            for (Enemy* enemy : enemy_list) {
                enemy->Draw(1000 / 144);
            }

            for (const Bullet& bullet : bullet_list) {
                bullet.Draw();
                UpdateBullets(bullet_list, player);

            }
            DrawPlayerScore(score);
            // 刷新批量绘制的内容到设备上
            FlushBatchDraw();

            // 获取当前时间戳
            DWORD end_time = GetTickCount();
            // 计算上一帧的绘制时间
            DWORD delta_time = end_time - start_time;
            // 如果绘制时间小于1/144秒，则等待相应的时间以达到稳定的帧率
            if (delta_time < 1000 / 144) {
                Sleep(1000 / 144 - delta_time);
            }
        }

        // 结束批量绘制
        EndBatchDraw();
        // 关闭图形界面
        closegraph();
    }
    
    

int main(){
    
    // 初始化图形界面，设置窗口大小为1280x720
    initgraph(WINDOW_WIDTH, WINDOW_HEIGHT);
    IMAGE menu;
    loadimage(&menu, _T("./img/menu1.png"), WINDOW_WIDTH, WINDOW_HEIGHT);
    putimage(0, 0, &menu);
    /*   setlinecolor(BLACK);
       setfillcolor(YELLOW);
       fillrectangle(560, 510, 720, 590);*/
       bool start = false;
       ExMessage msg;
       bool msg_1 = true;

       while (msg_1) {  // 不断的处理事务，需要循环
           if (peekmessage(&msg)) {
               switch (msg.message) {
               case WM_LBUTTONDOWN:  // 鼠标左键
                   if (msg.x >= 560 && msg.x <= 720 && msg.y >= 240 && msg.y <= 320) {  
                       //开始游戏 
                       gamestart();
                       break;
                   }
                   if (msg.x >= 560 && msg.x <= 720 && msg.y >= 330 && msg.y <= 410) {
                       //游戏设置
                         //建议开一个函数写
                       /*IMAGE gameset;
                       loadimage(&gameset, "./img/gameset.png", WINDOW_WIDTH, WINDOW_HEIGHT);
                       putimage(0, 0, &gameset);*/
                       break;
                   }
                   if (msg.x >= 560 && msg.x <= 720 && msg.y >= 420 && msg.y <= 500) {
                       //游戏介绍
                        //建议开一个函数写  
                      /*  IMAGE introduce;
                        loadimage(&introduce, "./img/introduce.png", WINDOW_WIDTH, WINDOW_HEIGHT);
                        putimage(0, 0, &introduce);*/
                       break;

                    }
                    if (msg.x >= 560 && msg.x <= 720 && msg.y >= 510 && msg.y <= 590) {
                        //排行榜
                          //建议开一个函数写
                        /*IMAGE rank;
                        loadimage(&rank, "./img/rank.png", WINDOW_WIDTH, WINDOW_HEIGHT);
                        putimage(0, 0, &rank);*/
                        break;
                    }
                    if (msg.x >= 560 && msg.x <= 720 && msg.y >= 620 && msg.y <= 700) {
                        exit(0);
                    }
                default:
                    break;
                }
            }
        }
       return 0;

}